/**
 * UI Manager for handling chat interface components
 */
import { wsManager } from "./websocket.js";

class UIManager {
    constructor() {
        this.currentRoom = null;
        this.currentUser = null;
        this.messages = [];
        this.users = [];
        
        this.messageContainer = null;
        this.messagesList = null;
        this.messageInput = null;
        this.usersList = null;
        
        this.isAtBottom = true;
        this.unreadCount = 0;
        this.isPageVisible = true;
        
        this.setupEventListeners();
        this.setupVisibilityListener();
    }

    /**
     * Setup global event listeners
     */
    setupEventListeners() {
        // WebSocket event listeners
        wsManager.on('joinSuccess', (data) => {
            this.handleJoinSuccess(data);
        });

        wsManager.on('newMessage', (data) => {
            this.handleNewMessage(data);
        });

        wsManager.on('userJoined', (data) => {
            this.handleUserJoined(data);
        });

        wsManager.on('userLeft', (data) => {
            this.handleUserLeft(data);
        });

        wsManager.on('roomUpdate', (data) => {
            this.handleRoomUpdate(data);
        });

        wsManager.on('connected', () => {
            this.showConnectionStatus('Connected', 'success');
        });

        wsManager.on('disconnected', () => {
            this.showConnectionStatus('Disconnected', 'error');
        });

        wsManager.on('reconnecting', (data) => {
            this.showConnectionStatus(`Reconnecting... (${data.attempt}/${wsManager.maxReconnectAttempts})`, 'warning');
        });

        wsManager.on('serverError', (data) => {
            showToast(data.message, 'error');
        });
    }

    /**
     * Setup page visibility listener for unread count
     */
    setupVisibilityListener() {
        document.addEventListener('visibilitychange', () => {
            this.isPageVisible = !document.hidden;
            if (this.isPageVisible) {
                this.unreadCount = 0;
                this.updatePageTitle();
            }
        });
    }

    /**
     * Setup room page UI
     */
    setupRoomPage(room, userSession) {
        this.currentRoom = room;
        this.currentUser = { nickname: userSession.nickname };
        
        // Get DOM elements
        this.messageContainer = document.getElementById('messages-container');
        this.messagesList = document.getElementById('messages-list');
        this.messageInput = document.getElementById('message-input');
        this.usersList = document.getElementById('users-list');
        
        // Update room header
        this.updateRoomHeader();
        
        // Setup message input
        this.setupMessageInput();
        
        // Setup room actions
        this.setupRoomActions();
        
        // Setup scroll detection
        this.setupScrollDetection();
        
        // Connect to WebSocket and join room
        this.connectToRoom(userSession);
        
        // Focus message input
        if (this.messageInput) {
            this.messageInput.focus();
        }
    }

    /**
     * Connect to WebSocket and join room
     */
    async connectToRoom(userSession) {
        try {
            this.showConnectionStatus('Connecting...', 'info');
            
            // Get WebSocket URL
            const protocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
            const wsUrl = `${protocol}//${window.location.host}/ws`;
            
            // Connect to WebSocket
            await wsManager.connect(wsUrl);
            
            // For room creators, use the existing userId from session
            // For joiners, userId will be null and server will create new one
            const userId = userSession.userId || sessionStorage.get('userId');
            
            // Join the room via WebSocket
            wsManager.joinRoom(
                this.currentRoom.id,
                userSession.nickname,
                userSession.password || null,
                userId // Pass existing userId for room creators
            );
            
        } catch (error) {
            console.error('Failed to connect to room:', error);
            this.showConnectionStatus('Connection failed', 'error');
            showToast('Failed to connect to room. Please refresh and try again.', 'error');
        }
    }

    /**
     * Handle successful room join
     */
    handleJoinSuccess(data) {
        this.currentUser = data.user;
        this.currentRoom = data.room;
        
        // Store user ID for reconnection
        sessionStorage.set('userId', data.user.id);
        
        // Load existing messages
        this.loadMessages(data.room.messages || []);
        
        // Update users list
        this.updateUsersList(data.room.members || []);
        
        this.showConnectionStatus('Connected', 'success');
        showToast(`Welcome to ${data.room.name}!`, 'success');
        
        // Hide connection status after a delay
        setTimeout(() => {
            this.hideConnectionStatus();
        }, 3000);
    }

    /**
     * Handle new message
     */
    handleNewMessage(data) {
        this.addMessage(data.message, data.user);
        
        // Update unread count if page is not visible
        if (!this.isPageVisible) {
            this.unreadCount++;
            this.updatePageTitle();
        }
        
        // Play notification sound (if implemented)
        this.playNotificationSound();
    }

    /**
     * Handle user joined
     */
    handleUserJoined(data) {
        showToast(data.message, 'info');
        this.addSystemMessage(data.message);
    }

    /**
     * Handle user left
     */
    handleUserLeft(data) {
        showToast(data.message, 'info');
        this.addSystemMessage(data.message);
    }

    /**
     * Handle room update
     */
    handleRoomUpdate(data) {
        this.updateUsersList(data.users);
        this.updateRoomMemberCount(data.memberCount);
    }

    /**
     * Setup message input
     */
    setupMessageInput() {
        const messageForm = document.getElementById('message-form');
        const sendBtn = document.getElementById('send-btn');
        
        if (messageForm && this.messageInput) {
            messageForm.addEventListener('submit', (event) => {
                event.preventDefault();
                this.sendMessage();
            });

            // Handle Enter key (without Shift)
            this.messageInput.addEventListener('keydown', (event) => {
                if (event.key === 'Enter' && !event.shiftKey) {
                    event.preventDefault();
                    this.sendMessage();
                }
            });

            // Auto-resize textarea
            this.messageInput.addEventListener('input', () => {
                autoResizeTextarea(this.messageInput);
            });

            // Update send button state
            this.messageInput.addEventListener('input', () => {
                const hasContent = this.messageInput.value.trim().length > 0;
                if (sendBtn) {
                    sendBtn.disabled = !hasContent || !wsManager.isConnected;
                }
            });
        }
    }

    /**
     * Setup room actions
     */
    setupRoomActions() {
        // Leave room button
        const leaveBtn = document.getElementById('leave-room-btn');
        if (leaveBtn) {
            leaveBtn.addEventListener('click', () => {
                this.leaveRoom();
            });
        }

        // Share invite button
        const inviteBtn = document.getElementById('invite-link-btn');
        if (inviteBtn) {
            inviteBtn.addEventListener('click', () => {
                this.showInviteModal();
            });
        }
    }

    /**
     * Setup scroll detection for auto-scroll
     */
    setupScrollDetection() {
        if (this.messageContainer) {
            this.messageContainer.addEventListener('scroll', throttle(() => {
                const { scrollTop, scrollHeight, clientHeight } = this.messageContainer;
                this.isAtBottom = scrollTop + clientHeight >= scrollHeight - 10;
            }, 100));
        }
    }

    /**
     * Send a message
     */
    sendMessage() {
        if (!this.messageInput || !wsManager.isConnected) {
            return;
        }

        const content = this.messageInput.value.trim();
        if (!content) {
            return;
        }

        if (content.length > 1000) {
            showToast('Message is too long (max 1000 characters)', 'error');
            return;
        }

        // Send message via WebSocket
        const success = wsManager.sendMessage(content);
        
        if (success) {
            // Clear input
            this.messageInput.value = '';
            this.messageInput.style.height = 'auto';
            
            // Update send button state
            const sendBtn = document.getElementById('send-btn');
            if (sendBtn) {
                sendBtn.disabled = true;
            }
        } else {
            showToast('Failed to send message. Please try again.', 'error');
        }
    }

    /**
     * Leave the current room
     */
    leaveRoom() {
        if (confirm('Are you sure you want to leave this room?')) {
            wsManager.leaveRoom();
            wsManager.disconnect();
            
            // Clear session data
            sessionStorage.remove('currentUser');
            sessionStorage.remove('userId');
            
            // Navigate to home
            router.navigate('/');
            
            showToast('Left the room', 'info');
        }
    }

    /**
     * Load existing messages
     */
    loadMessages(messages) {
        this.messages = messages;
        this.renderMessages();
    }

    /**
     * Add a new message
     */
    addMessage(message, user) {
        this.messages.push(message);
        this.renderMessage(message, user);
        this.scrollToBottom();
    }

    /**
     * Add a system message
     */
    addSystemMessage(content) {
        const systemMessage = {
            id: generateId(),
            userId: 'system',
            content: content,
            type: 'system',
            timestamp: new Date().toISOString()
        };
        
        this.messages.push(systemMessage);
        this.renderMessage(systemMessage);
        this.scrollToBottom();
    }

    /**
     * Render all messages
     */
    renderMessages() {
        if (!this.messagesList) return;
        
        this.messagesList.innerHTML = '';
        
        this.messages.forEach(message => {
            const user = this.users.find(u => u.id === message.userId);
            this.renderMessage(message, user, false);
        });
        
        this.scrollToBottom();
    }

    /**
     * Render a single message
     */
    renderMessage(message, user = null, animate = true) {
        if (!this.messagesList) return;
        
        const messageEl = this.createMessageElement(message, user);
        
        if (animate) {
            messageEl.style.opacity = '0';
            messageEl.style.transform = 'translateY(20px)';
        }
        
        this.messagesList.appendChild(messageEl);
        
        if (animate) {
            // Trigger animation
            requestAnimationFrame(() => {
                messageEl.style.transition = 'opacity 0.3s ease-out, transform 0.3s ease-out';
                messageEl.style.opacity = '1';
                messageEl.style.transform = 'translateY(0)';
            });
        }
    }

    /**
     * Create message element
     */
    createMessageElement(message, user = null) {
        const messageEl = document.createElement('div');
        messageEl.className = 'message';
        
        if (message.type === 'system') {
            messageEl.classList.add('message-system');
            messageEl.innerHTML = `
                <div class="message-content">
                    <div class="message-text">${sanitizeHtml(message.content)}</div>
                    <div class="message-time">${formatTime(message.timestamp)}</div>
                </div>
            `;
        } else {
            const isOwnMessage = message.userId === this.currentUser?.id;
            messageEl.classList.add(isOwnMessage ? 'message-own' : 'message-other');
            
            const userName = user?.nickname || 'Unknown User';
            const userInitials = getInitials(userName);
            const avatarColor = getAvatarColor(userName);
            
            messageEl.innerHTML = `
                <div class="message-avatar" style="background-color: ${avatarColor}">
                    ${userInitials}
                </div>
                <div class="message-content">
                    ${!isOwnMessage ? `<div class="message-author">${sanitizeHtml(userName)}</div>` : ''}
                    <div class="message-text">${parseUrls(message.content)}</div>
                    <div class="message-time">${formatTime(message.timestamp)}</div>
                </div>
            `;
        }
        
        return messageEl;
    }

    /**
     * Update users list
     */
    updateUsersList(users) {
        this.users = users;
        
        if (!this.usersList) return;
        
        this.usersList.innerHTML = '';
        
        users.forEach(user => {
            const userEl = this.createUserElement(user);
            this.usersList.appendChild(userEl);
        });
    }

    /**
     * Create user element
     */
    createUserElement(user) {
        const userEl = document.createElement('div');
        userEl.className = 'user-item';
        
        const initials = getInitials(user.nickname);
        const avatarColor = getAvatarColor(user.nickname);
        const isCurrentUser = user.id === this.currentUser?.id;
        
        userEl.innerHTML = `
            <div class="user-avatar" style="background-color: ${avatarColor}">
                ${initials}
            </div>
            <div class="user-info">
                <div class="user-name">
                    ${sanitizeHtml(user.nickname)}
                    ${isCurrentUser ? ' (You)' : ''}
                </div>
                <div class="user-status ${user.isOnline ? 'user-online' : ''}">
                    ${user.isOnline ? 'Online' : 'Offline'}
                </div>
            </div>
        `;
        
        return userEl;
    }

    /**
     * Update room header
     */
    updateRoomHeader() {
        const roomTitle = document.getElementById('room-title');
        const roomMemberCount = document.getElementById('room-member-count');
        
        if (roomTitle && this.currentRoom) {
            roomTitle.textContent = this.currentRoom.name;
        }
        
        if (roomMemberCount && this.currentRoom) {
            roomMemberCount.textContent = this.currentRoom.memberCount || 0;
        }
    }

    /**
     * Update room member count
     */
    updateRoomMemberCount(count) {
        const roomMemberCount = document.getElementById('room-member-count');
        if (roomMemberCount) {
            roomMemberCount.textContent = count;
        }
        
        if (this.currentRoom) {
            this.currentRoom.memberCount = count;
        }
    }

    /**
     * Scroll to bottom of messages
     */
    scrollToBottom() {
        if (this.messageContainer && this.isAtBottom) {
            setTimeout(() => {
                this.messageContainer.scrollTop = this.messageContainer.scrollHeight;
            }, 100);
        }
    }

    /**
     * Show invite modal
     */
    showInviteModal() {
        const modal = document.getElementById('invite-modal');
        const inviteLinkInput = document.getElementById('invite-link-input');
        const copyBtn = document.getElementById('copy-invite-btn');
        const closeBtn = document.getElementById('invite-modal-close');
        
        if (!modal || !this.currentRoom) return;
        
        // Generate invite URL
        const inviteUrl = `${window.location.origin}/join/${this.currentRoom.inviteCode}`;
        
        if (inviteLinkInput) {
            inviteLinkInput.value = inviteUrl;
        }
        
        // Setup copy button
        if (copyBtn) {
            copyBtn.onclick = async () => {
                const success = await copyToClipboard(inviteUrl);
                if (success) {
                    showToast('Invite link copied to clipboard!', 'success');
                    copyBtn.textContent = 'Copied!';
                    setTimeout(() => {
                        copyBtn.textContent = 'Copy';
                    }, 2000);
                } else {
                    showToast('Failed to copy invite link', 'error');
                }
            };
        }
        
        // Setup close button
        if (closeBtn) {
            closeBtn.onclick = () => {
                modal.classList.add('hidden');
            };
        }
        
        // Show modal
        modal.classList.remove('hidden');
        
        // Close on background click
        modal.onclick = (event) => {
            if (event.target === modal) {
                modal.classList.add('hidden');
            }
        };
    }

    /**
     * Show connection status
     */
    showConnectionStatus(message, type) {
        // Could implement a connection status indicator
        console.log(`Connection: ${message} (${type})`);
    }

    /**
     * Hide connection status
     */
    hideConnectionStatus() {
        // Could hide connection status indicator
    }

    /**
     * Update page title with unread count
     */
    updatePageTitle() {
        const baseTitle = this.currentRoom ? 
            `${this.currentRoom.name} - LAN Chat Room` : 
            'LAN Chat Room';
        
        document.title = this.unreadCount > 0 ? 
            `(${this.unreadCount}) ${baseTitle}` : 
            baseTitle;
    }

    /**
     * Play notification sound (placeholder)
     */
    playNotificationSound() {
        // Could implement audio notification
        // For now, just use browser notification API if available
        if ('Notification' in window && Notification.permission === 'granted') {
            // Could show desktop notification for background tabs
        }
    }

    /**
     * Clear all UI state
     */
    clear() {
        this.currentRoom = null;
        this.currentUser = null;
        this.messages = [];
        this.users = [];
        this.unreadCount = 0;
        this.updatePageTitle();
    }
}

// Global UI manager instance
const ui = new UIManager();

// Export for use in other modules
export {ui};